<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h2 data-lake-id="zr668" id="zr668"><span data-lake-id="u378a300b" id="u378a300b">run方法和start方法区别</span></h2>
  <p data-lake-id="udb176c01" id="udb176c01"><br></p>
  <p data-lake-id="u3a5093d3" id="u3a5093d3"><span data-lake-id="u0b74ba44" id="u0b74ba44">我们创建好线程之后，想要启动这个线程，则需要调用其start方法。所以，</span><strong><span data-lake-id="uba445587" id="uba445587">start方法是启动一个线程的入口。</span></strong></p>
  <p data-lake-id="u65ba56a1" id="u65ba56a1"><span data-lake-id="u467c29ba" id="u467c29ba">​</span><br></p>
  <p data-lake-id="uc45e34d7" id="uc45e34d7"><span data-lake-id="u3b6174c5" id="u3b6174c5">如果在创建好线程之后，直接调用其run方法，那么就会在单线程中直接运行run方法，不会起到多线程的效果。</span></p>
  <p data-lake-id="u3b8ae4b0" id="u3b8ae4b0"><span data-lake-id="uce5b3294" id="uce5b3294">​</span><br></p>
  <h2 data-lake-id="SKwe3" id="SKwe3"><span data-lake-id="u320be185" id="u320be185">sleep和wait区别</span></h2>
  <p data-lake-id="u534125b8" id="u534125b8"><span data-lake-id="u5baa8962" id="u5baa8962">​</span><br></p>
  <p data-lake-id="uf8b2a567" id="uf8b2a567"><span data-lake-id="u5c56e51a" id="u5c56e51a">sleep()方法可以在任何地方使用；而</span><strong><span data-lake-id="uf1125f01" id="uf1125f01">wait()方法则只能在同步方法或同步块中使用</span></strong><span data-lake-id="u015b727b" id="u015b727b">。</span></p>
  <p data-lake-id="u2f622318" id="u2f622318"><span data-lake-id="ubd77b066" id="ubd77b066">​</span><br></p>
  <p data-lake-id="u558b44ec" id="u558b44ec"><strong><span data-lake-id="u74edbce5" id="u74edbce5">wait 方法会释放对象锁</span></strong><span data-lake-id="u646ae8b4" id="u646ae8b4">，但 sleep 方法不会。</span></p>
  <p data-lake-id="u9df03cee" id="u9df03cee"><span data-lake-id="u559884a6" id="u559884a6">​</span><br></p>
  <p data-lake-id="u647364b7" id="u647364b7"><strong><span data-lake-id="u14474b10" id="u14474b10">wait的线程会进入到WAITING状态，直到被唤醒</span></strong><span data-lake-id="ue5e16fd8" id="ue5e16fd8">；sleep的线程会进入到TIMED_WAITING状态，等到指定时间之后会再尝试获取CPU时间片。</span></p>
  <p data-lake-id="u38a4e9d5" id="u38a4e9d5"><span data-lake-id="u30988cb3" id="u30988cb3">​</span><br></p>
  <p data-lake-id="ue7a124de" id="ue7a124de"><span data-lake-id="ub12c58e9" id="ub12c58e9">因为Java锁的目标是对象，而wait需要释放锁，所以针对的目标都是对象，所以把他定义在Object类中。 而sleep()不需要释放锁，所以他针对的目标是线程，所以定义在Thread类中。 </span></p>
  <h2 data-lake-id="Lbol6" id="Lbol6"><span data-lake-id="u38a8cc95" id="u38a8cc95">notify和notifyAll区别</span></h2>
  <p data-lake-id="u23919379" id="u23919379"><br></p>
  <p data-lake-id="u02d85821" id="u02d85821"><span data-lake-id="u2ab5d52a" id="u2ab5d52a">当一个线程进入wait之后，就必须等其他线程notify()/notifyAll()，才会从等待队列中被移出。</span></p>
  <p data-lake-id="u08e3312a" id="u08e3312a"><span data-lake-id="u932f06b7" id="u932f06b7">​</span><br></p>
  <p data-lake-id="u2a71195e" id="u2a71195e"><strong><span data-lake-id="u7bd681ba" id="u7bd681ba">使用notifyAll，可以唤醒所有处于wait状态的线程，使其重新进入锁的争夺队列中，而notify只能唤醒一个。</span></strong></p>
  <p data-lake-id="u8850b3c7" id="u8850b3c7"><span data-lake-id="u79dab65b" id="u79dab65b">​</span><br></p>
  <p data-lake-id="ue64b6806" id="ue64b6806"><span data-lake-id="ue98aa529" id="ue98aa529">但是唤醒的这些线程只是进入争夺队列，并不表示立即就可以获得CPU开始执行，因为wait方法被调用的时候，线程已经释放了对象锁。</span></p>
  <p data-lake-id="u9c225fb8" id="u9c225fb8"><span data-lake-id="ub22535cf" id="ub22535cf">​</span><br></p>
  <p data-lake-id="u58912793" id="u58912793"><span data-lake-id="uee197526" id="uee197526">所以，被notify()/notifyAll()唤醒的线程，只是表示他们可以竞争锁了，竞争到锁之后才有机会被CPU调度。</span></p>
  <p data-lake-id="uadfc99c4" id="uadfc99c4"><span data-lake-id="ua6c82b79" id="ua6c82b79">​</span><br></p>
  <p data-lake-id="u0867e6d2" id="u0867e6d2"><span data-lake-id="uae80269a" id="uae80269a">那么notifyAll虽然可以把所有线程都唤醒，让他们都可以竞争锁，但是最终也只有一个可以获得锁并执行。</span></p>
  <p data-lake-id="u241b565e" id="u241b565e"><br></p>
  <p data-lake-id="u740f8620" id="u740f8620"><strong><span data-lake-id="ue341d229" id="ue341d229">notify和notifyAll因为也是操作对象的，所以把他们定义在Object类中。</span></strong></p>
 </body>
</html>